package yhao.infra.web.interceptor;

import org.slf4j.Logger;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import yhao.infra.common.YhaoInfraCommonProperties;
import yhao.infra.web.YhaoInfraWebProperties;
import yhao.infra.web.filter.WebSessionFilter;
import yhao.infra.web.interceptor.logger.context.RequestContext;
import yhao.infra.web.interceptor.logger.context.RequestContextHolder;
import yhao.infra.web.interceptor.logger.support.StatWebLoggerBuilder;
import yhao.infra.web.interceptor.logger.support.LoggerBuilder;
import yhao.infra.common.logger.CommonLoggerFactory;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * @author yoara
 * <p> Created on 2019/4/19 </p>
 */
public class WebAccessLoggerInterceptor implements AsyncHandlerInterceptor {
    private Logger logger;

    private String appName;
    private LoggerBuilder loggerBuilder;
    private Class<? extends RequestContext> contextClazz;

    public WebAccessLoggerInterceptor setLogger(Logger logger) {
        this.logger = logger;
        return this;
    }

    /**
     * @param loggerBuilder 可为空 {@link StatWebLoggerBuilder#doLog(HttpServletRequest, RequestContext)}
     */
    public WebAccessLoggerInterceptor(Environment env,
                                      LoggerBuilder loggerBuilder, Class<? extends RequestContext> contextClazz) {
        this.appName = env.getProperty(YhaoInfraCommonProperties.ENV_APP_NAME,"undefined");
        this.logger = builderWebAccessLogger(env);
        this.loggerBuilder = loggerBuilder==null?new StatWebLoggerBuilder():loggerBuilder;
        this.contextClazz = contextClazz==null?RequestContext.class:contextClazz;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        RequestContextHolder.init(appName,contextClazz);
        try{
            RequestContextHolder.getDigestContext().setSessionId((String)request.getAttribute(WebSessionFilter.getSessionId()));
        }catch (Exception e){
            RequestContextHolder.getDigestContext().setSessionId("-");
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        RequestContext digestContext =RequestContextHolder.getDigestContext();
        logger.info(loggerBuilder.doLog(request,digestContext));
        RequestContextHolder.clear();
    }

    public static Logger builderWebAccessLogger(Environment env){
        String loggerPath = env.getProperty(YhaoInfraWebProperties.WEB_LOG_PATH,"/log/");
        String webLogPath = (CommonLoggerFactory.isSystemWindows() ? "c:" : "")
                + loggerPath +"stat_logs/"
                + env.getProperty(YhaoInfraCommonProperties.ENV_APP_NAME)
                + env.getProperty("server.port","");
        return CommonLoggerFactory.makeRollingFileLogger(new CommonLoggerFactory.LoggerParam(
                webLogPath,"stat",WebAccessLoggerInterceptor.class));
    }
}
